/**
 * Copyright (c) 2009  Collaborative Development Group, C.S. Dept., University of Bari
 *
 * All rights reserved. This program and the accompanying materials are made available under
 * the terms of the Eclipse Public License v1.0  which accompanies this distribution, and is 
 * available at http://www.eclipse.org/legal/epl-v10.html
 */
package it.uniba.di.cdg.penelope.presenterfirst;

import static it.uniba.di.cdg.penelope.presenterfirst.PropertyMatcher.isProperty;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.mockito.Mockito.verify;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import org.mockito.ArgumentCaptor;
import org.mockito.Mockito;

import com.google.inject.Binder;
import com.google.inject.Provider;

/**
 * Default mocks when testing.
 */
public class TestHelpers {
	/**
	 * Configure the injector to bind a Mockito mock for the given type.
	 * @param <T>
	 * @param binder
	 * @param type
	 */
	public static <T> void mockDependency( Binder binder, Class<T> type ) {
		binder.bind( type ).toInstance( Mockito.mock( type ) );
	}

	public static <T> void mockProvider( Binder binder, final Class<T> type ) {
		binder.bind( type ).toProvider( new Provider<T>() {
			@Override
			public T get() {
				return Mockito.mock( type );
			}
		});
	}
	
	public static <T> PropertyChangeEvent mockChangeEvent( Object source, String propertyName, T oldValue, T newValue ) {
		return new PropertyChangeEvent( source, propertyName, oldValue, newValue );
	}
	
	
	/**
	 * Ensure that a {@link PropertyChangeListener} has been invoked with the expected values.
	 * @param listener
	 * @param propertyName
	 * @param oldValue
	 * @param newValue
	 */
	public static void assertPropertyChangeListenerNotified( PropertyChangeListener listener, String propertyName, Object oldValue, Object newValue ) {
		ArgumentCaptor<PropertyChangeEvent> argument = ArgumentCaptor.forClass( PropertyChangeEvent.class );
		
		verify( listener ).propertyChange( argument.capture() );
		assertThat( argument.getValue(), isProperty( propertyName, oldValue, newValue ) );
	}
}
